
#global parameters
Rho = 10
Y = []
X = []

R = []    # xi*xj

W = []
B = 0

dataFileName = "F:\\svmtest\data1.txt"

#inner product
def innerProduct(X,Y):
    if len(X) != len(Y):
        return 0
		
    z = 0
    for i in range(len(X)):
        z += X[i] * Y[i]
    return z

#load data
def loadData():
    global X
    global Y
    global R
    global dataFileName
    
    file = open(dataFileName,"r",encoding="GBK")

    for lines in file.readlines():
        label = lines[0:lines.find(" ")]
        lines = lines[lines.find(" ")+1:]
        
        Y.append(int(label))
        xi = []
        
        for kv in lines.split(" "):
            data = float(kv[kv.find(":")+1:])
            xi.append(data)
            
        X.append(xi)
        
    file.close()

    #output data
    #for i in range(len(X)):
    #    print(str(i) + ":" + str(X[i]))
	
	#compute R
    for i in range(len(X)):
        xi = []
        for j in range(len(X)):
            xi.append(innerProduct(X[i],X[j]))

        R.append(xi)

    print(str(R))

#compute W,B
def compute():
    global W
    global B

    success = "NO"
    wave = 0

    W = [0] * len(X[0])

    while success == "NO":
        wave += 1
        
    #    if wave == 10:
    #        break
        
        if wave > 1000000:
            print("dam...")
            raise SystemExit

        print("Wave " + str(wave) + "....")
    #    print ("W = " + str(W))
    #    print("B = " + str(B))
        
        for i in range(len(X)):
            fxi = B
            for j in range(len(W)):
    #            print("i:"+str(i))
    #            print("j:"+str(j))
    #            print("len(W):"+str(len(W)))
    #            print("len(X[i]):"+str(len(X[i])))
    #            print("X[i]:"+str(X[i]))
    #            print("W:"+str(W))
                fxi += W[j] * X[i][j]
                
                if fxi > 0:
                    fxi = 1
                else:
                    fxi = -1
                
            sign = fxi * Y[i]
            
            #error point update W,B
            if sign < 0:
    #            print("i:"+str(i))
    #            print("Rho:"+str(Rho))
    #            print("fxi:"+str(fxi))
    #            print("Y[i]:"+str(Y[i]))
                delta = (Y[i] - fxi) * Rho / 2
                B += delta
                for k in range(len(W)):
                    W[k] += delta * X[i][k]
                break
                    
            if i == len(X) - 1:
                success = "YES"

#    print ("W = " + str(W))
#    print("B = " + str(B))

#compute W,B using inner product
def computeDual():
    global W
    global B
    global X
    global Y
    global R
	
    gotIt = "YES"
    wave = 0

    W = [0] * len(X[0])
    alpha = [0] * len(X)
    
    while True:
        gotIt = "YES"
        wave += 1
        if wave > 1000:
            print("dam...")
            raise SystemExit
            
        print("Wave " + str(wave) + "....")
        for i in range(len(X)):
            sum = 0
            for j in range(len(X)):
#                print("i:"+str(i))
#                print("j:"+str(j))
#                print("len(alpha):"+str(len(alpha)))
#                print("len(Y):"+str(len(Y)))
#                print("len(R):"+str(len(R)))
#                print("len(R[i]):"+str(len(R[i])))
#
#                print ("W = " + str(W))
#                print("B = " + str(B))
#                print ("alpha = " + str(alpha))
                
                sum += alpha[j] * Y[j] * R[i][j]
#                print ("sum = " + str(sum))
#                print ("Y[i] * (sum + B) = " + str(Y[i] * (sum + B)))
				
            if Y[i] * (sum + B) <= 0:
                alpha[i] += Rho
                B += Rho * Y[i]
                gotIt = "NO"
        if gotIt == "YES":
           break

    for i in range(len(X)):
        for j in range(len(X[i])):
            W[j] += alpha[i] * Y[i] * X[i][j]

#    print ("W = " + str(W))
#    print("B = " + str(B))
		
#valid model
def validModel():
    global X
    global Y
    global W
    global B

    error_count = 0
    sign = 0
    for i in range(len(X)):
        for i in range(len(X)):
            fxi = B
            for j in range(len(W)):
                fxi += W[j] * X[i][j]
                
                if fxi > 0:
                    fxi = 1
                else:
                    fxi = -1
                
            sign = fxi * Y[i]
            
        
        if sign <0:
            error_count += 1
            print("Y[i]:" + Y[i])
            print("WX+B:" + str(W[0]*X[i][0] + W[1]*X[i][1] + B))

    print("classify error count:" + str(error_count))

loadData()
compute()
#computeDual()
validModel()

print ("W = " + str(W))
print("B = " + str(B))
